﻿/*!
* Useless Tetris Game http://uselessgames.codeplex.com
*
* Copyright 2014 Filip Srbinovski
* Released under the Apache License
*
* Useless Tetris Game © Filip Srbinovski - Version [0.1] 
*/

// ---------------------------------- Constructors -------------------------------- //
var blockT = {
    north: function (coordX, coordY) {
        return [
        { x: coordX, y: coordY },
        { x: coordX, y: coordY + 1 },
        { x: coordX, y: coordY + 2 },
        { x: coordX + 1, y: coordY + 1 }
        ];
    },

    east: function (coordX, coordY) {
        return [
        { x: coordX, y: coordY + 1 },
        { x: coordX + 1, y: coordY + 1 },
        { x: coordX + 2, y: coordY + 1 },
        { x: coordX + 1, y: coordY }
        ];
    },

    south: function (coordX, coordY) {
        return [
        { x: coordX, y: coordY + 1 },
        { x: coordX + 1, y: coordY },
        { x: coordX + 1, y: coordY + 1 },
        { x: coordX + 1, y: coordY + 2 }
        ];
    },

    west: function (coordX, coordY) {
        return [
        { x: coordX, y: coordY },
        { x: coordX + 1, y: coordY },
        { x: coordX + 2, y: coordY },
        { x: coordX + 1, y: coordY + 1 }
        ];
    }
}

var blockZ = {
    horizontal: function (coordX, coordY) {
        return [
            { x: coordX, y: coordY },
            { x: coordX, y: coordY + 1 },
            { x: coordX + 1, y: coordY + 1 },
            { x: coordX + 1, y: coordY + 2 },
        ];
    },

    vertical: function (coordX, coordY) {
        return [
            { x: coordX, y: coordY + 1 },
            { x: coordX + 1, y: coordY + 1 },
            { x: coordX + 1, y: coordY },
            { x: coordX + 2, y: coordY }
        ];
    }
}

var blockS = {
    horizontal: function (coordX, coordY) {
        return [
            { x: coordX, y: coordY + 1 },
            { x: coordX, y: coordY + 2 },
            { x: coordX + 1, y: coordY  },
            { x: coordX + 1, y: coordY + 1 }
        ];
    },

    vertical: function (coordX, coordY) {
        return [
            { x: coordX, y: coordY },
            { x: coordX + 1, y: coordY },
            { x: coordX + 1, y: coordY + 1 },
            { x: coordX + 2, y: coordY + 1 }
        ];
    }
}

var blockI = {
    horizontal: function (coordX, coordY) {
        return [
                { x: coordX, y: coordY },
                { x: coordX, y: coordY + 1 },
                { x: coordX, y: coordY + 2 },
                { x: coordX, y: coordY + 3 },
        ]
    },

    vertical: function (coordX, coordY) {
        return [
            { x: coordX, y: coordY },
            { x: coordX + 1, y: coordY },
            { x: coordX + 2, y: coordY },
            { x: coordX + 3, y: coordY },
        ];
    }
}

var blockL = {
    
}

var blockJ = {

}

var blockO = {

}

// ---------------------------------- Game Objects -------------------------------- //

function BlockZ(coordX, coordY) {
    this.x = coordX;
    this.y = coordY;
    this.horizontal = true;
}

BlockZ.prototype.rotate = function () {
    this.horizontal = !this.horizontal;
}

BlockZ.prototype.getBody = function () {
    if (this.horizontal) {
       return blockZ.vertical(this.x, this.y);
    }
    else {
       return blockZ.horizontal(this.x, this.y);
    }
}

function BlockS(coordX, coordY) {
    this.x = coordX;
    this.y = coordY;

    this.horizontal = true;
}

BlockS.prototype.rotate = function () {
    this.horizontal = !this.horizontal;
}

BlockS.prototype.getBody = function () {
    if (this.horizontal) {
        return blockS.vertical(this.x, this.y);
    }
    else {
        return blockS.horizontal(this.x, this.y);
    }
}

function BlockI(coordX, coordY) {
    this.x = coordX;
    this.y = coordY;

    this.horizontal = true;
}

BlockI.prototype.rotate = function () {
    this.horizontal = !this.horizontal;
}

BlockI.prototype.getBody = function () {
    if (this.horizontal) {
        return blockI.vertical(this.x, this.y);
    }
    else {
        return blockI.horizontal(this.x, this.y);
    }
}

function BlockT(coordX, coordY) {
    this.x = coordX;
    this.y = coordY;

    this.currentDirection = 0;
}

BlockT.prototype.rotate = function () {
    this.currentDirection++;
    this.currentDirection %= 4;
}

BlockT.prototype.getBody = function () {
    switch (this.currentDirection) {
        case 0:
            return blockT.north(this.x, this.y);
        case 1:
            return blockT.west(this.x, this.y);
        case 2:
            return blockT.south(this.x, this.y);
        case 3:
            return blockT.east(this.x, this.y);
    }
}

function blockFactory() {
    var randNumber = Math.floor((Math.random() * 100 + 1)) % 4;
    var randCoord = Math.floor((Math.random() * 100 + 1)) % 9;

    switch (randNumber) {
        case 0:
            return new BlockZ(0, randCoord);
        case 1:
            return new BlockS(0, randCoord);
        case 2:
            return new BlockZ(0, randCoord);
        case 3:
            return new BlockI(0, randCoord);

    }
}

// ---------------------------------- Game Logic -------------------------------- //

var field = [];
var ROWS = 19;
var COLS = 11;

function initField() {

    var htmlField = document.getElementById('field');
    var node = document.createElement('div');
    node.src = 'resources/block.png';
    node.className = 'block';

    for (var i = 0; i < ROWS; i++) {
        field[i] = [];
        for (var j = 0; j < COLS; j++) {
            var clonedNode = node.cloneNode(true);
            field[i][j] = clonedNode;
            htmlField.appendChild(field[i][j]);
        }
    }
}

function renderGameObject(block) {
    var body = block.getBody();
    for (var i = 0; i < body.length; i++) {
        if (body[i].x < ROWS) {
            field[body[i].x][body[i].y].style.visibility = 'visible';
        }
    }
}

function clearGameObject(block) {
    var body = block.getBody();
    for (var i = 0; i < body.length; i++) {
        if (body[i].x < ROWS) {
            field[body[i].x][body[i].y].style.visibility = 'hidden';
        }
    }
}

function moveBlock(block) {
    block.x++;
}

var mainLoopInterval;

function startGame() {
    initField();
    
    var fallingBlock = blockFactory();
    renderGameObject(fallingBlock);    
    
    function mainLoop() {
        clearGameObject(fallingBlock);
        
        moveBlock(fallingBlock);
        renderGameObject(fallingBlock);

        if (fallingBlock.x > ROWS) {
            fallingBlock = blockFactory();
            renderGameObject(fallingBlock);
        }
    }


    function leftArrowPressed() {
        if (fallingBlock.y > 0) {
            clearGameObject(fallingBlock);
            fallingBlock.y--;
            renderGameObject(fallingBlock);
        }
    }

    function getMaxOffset(block) {
        var body = block.getBody();
        var blockCoordY = block.y;
        var maxOffset = body[0].y - blockCoordY;
        for (var i = 1; i < body.length; i++) {
            if (body[i].y - blockCoordY > maxOffset) {
                maxOffset = body[i].y - blockCoordY;
            }
        }
        return maxOffset;
    }

    function rightArrowPressed() {
        var maxOffset = getMaxOffset(fallingBlock);

        if (fallingBlock.y < COLS - maxOffset - 1) {
            clearGameObject(fallingBlock);
            fallingBlock.y++;
            renderGameObject(fallingBlock);
        }
    }

    function spaceKeyPressed() {
        clearGameObject(fallingBlock);
        fallingBlock.rotate();
        var offset = getMaxOffset(fallingBlock);
        if (fallingBlock.y + offset >= COLS) {
            fallingBlock.y = COLS - offset - 1;
        }
        
        renderGameObject(fallingBlock);
    }

    window.onkeydown = function (e) {
        e = e || window.event;
        switch (e.keyCode) {
            case 37:
                leftArrowPressed();
                break;
            case 39:
                rightArrowPressed();
                break;
            case 32:
                spaceKeyPressed();
                break;
        }
    }

    mainLoopInterval = window.setInterval(mainLoop, 200);
}

